import java.util.Deque;
import java.util.LinkedList;
import java.util.Scanner;

/**
 * Created with IntelliJ IDEA.
 * Description: 子矩阵
 * User: DELL
 * Date: 2024-03-15
 * Time: 22:02
 */
public class Demo2 {

    public static final int temp = 998244353;

    /**
     * 总体上运用滑动窗口在行和列上求矩阵的最大和最小值
     *
     * @param args
     */
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        int m = scanner.nextInt();
        int a = scanner.nextInt();
        int b = scanner.nextInt();
        int[][] arr = new int[n][m];
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                arr[i][j] = scanner.nextInt();
            }
        }
        // 预处理
        int[][] rowMax = new int[n][m];
        int[][] rowMin = new int[n][m];
        processMax(arr, rowMax, b);
        processMin(arr, rowMin, b);

        long sum = 0;
        for (int col = b - 1; col < m; col++) {
            Deque<Long> dequeMax = new LinkedList<>();
            Deque<Long> dequeMin = new LinkedList<>();
            for (int row = 0; row < a; row++) {
                while (!dequeMax.isEmpty() && dequeMax.getLast() < rowMax[row][col]) {
                    dequeMax.removeLast();
                }
                dequeMax.addLast((long) rowMax[row][col]);
                while (!dequeMin.isEmpty() && dequeMin.getLast() > rowMin[row][col]) {
                    dequeMin.removeLast();
                }
                dequeMin.addLast((long) rowMin[row][col]);
            }
            sum += dequeMax.getFirst() * dequeMin.getFirst();
            sum %= temp;

            for (int row = a; row < n; row++) {
                while (!dequeMax.isEmpty() && dequeMax.getLast() < rowMax[row][col]) {
                    dequeMax.removeLast();
                }
                while (!dequeMin.isEmpty() && dequeMin.getLast() > rowMin[row][col]) {
                    dequeMin.removeLast();
                }
                dequeMin.addLast((long) rowMin[row][col]);
                dequeMax.addLast((long) rowMax[row][col]);
                if ((long) rowMax[row - a][col] == dequeMax.getFirst()) {
                    dequeMax.removeFirst();
                }
                if ((long) rowMin[row - a][col] == dequeMin.getFirst()) {
                    dequeMin.removeFirst();
                }
                sum += dequeMax.getFirst() * dequeMin.getFirst();
                sum %= temp;
            }
        }
        System.out.println(sum);
    }

    private static void processMax(int[][] arr, int[][] rowMax, int b) {
        int row = arr.length;
        int col = arr[0].length;
        for (int i = 0; i < row; i++) {
            Deque<Integer> deque = new LinkedList<>();
            deque.add(arr[i][0]);
            for (int j = 1; j < b; j++) {
                while (!deque.isEmpty() && arr[i][j] > deque.getLast()) {
                    deque.removeLast();
                }
                deque.addLast(arr[i][j]);
            }
            rowMax[i][b - 1] = deque.getFirst();
            for (int j = b; j < col; j++) {
                while (!deque.isEmpty() && arr[i][j] > deque.getLast()) {
                    deque.removeLast();
                }
                deque.addLast(arr[i][j]);
                if (arr[i][j - b] == deque.getFirst()) {
                    deque.removeFirst();
                }
                rowMax[i][j] = deque.getFirst();
            }
        }
    }

    private static void processMin(int[][] arr, int[][] rowMin, int b) {
        int row = arr.length;
        int col = arr[0].length;
        for (int i = 0; i < row; i++) {
            Deque<Integer> deque = new LinkedList<>();
            deque.add(arr[i][0]);
            for (int j = 1; j < b; j++) {
                while (!deque.isEmpty() && arr[i][j] < deque.getLast()) {
                    deque.removeLast();
                }
                deque.addLast(arr[i][j]);
            }
            rowMin[i][b - 1] = deque.getFirst();
            for (int j = b; j < col; j++) {
                while (!deque.isEmpty() && arr[i][j] < deque.getLast()) {
                    deque.removeLast();
                }
                deque.addLast(arr[i][j]);
                if (arr[i][j - b] == deque.getFirst()) {
                    deque.removeFirst();
                }
                rowMin[i][j] = deque.getFirst();
            }
        }
    }
}












